package com.link_with_health.common;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

public class TokenMap {
    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private volatile static TokenMap tokenMapObj = new TokenMap();
    private static final Map<String, TokenMap.TokenEntry<String, Object>> tokenMap
            = new ConcurrentHashMap<String, TokenMap.TokenEntry<String, Object>>();// 验签容器
    private static final long CLEAR_TIMEOUT = 1000 * 60 * 60 * 8;
    private static final long CHECK_TIMEOUT = 1000 * 60 * 30;

    private TokenMap() {
        new TokenMap.ClearThread().start();
    }

    /**
     * 采用单例模式获取缓存对象实例
     */
    public static synchronized TokenMap getInstance() {
        return tokenMapObj;
    }


    private class TokenEntry<K, V> implements Map.Entry<K, V> {
        long time;
        V value;
        K key;

        TokenEntry(K key, V value) {
            super();
            this.value = value;
            this.key = key;
            this.time = System.currentTimeMillis();
        }

        @Override
        public K getKey() {
            return key;
        }

        @Override
        public V getValue() {
            return value;
        }

        @Override
        public V setValue(V value) {
            return this.value = value;
        }
    }

    private class ClearThread extends Thread {
        ClearThread() {
            setName("clear cache thread");
        }

        public void run() {
            while (true) {
                long now = System.currentTimeMillis();
                SimpleDateFormat sdf =  new SimpleDateFormat(  "yyyy-MM-dd HH:mm:ss" );
                logger.info("[定时检查: " + sdf.format(now) + " >> " + tokenMap.size()+"]");
                Set<String> keys = tokenMap.keySet();
                for (String key : keys) {
                    TokenMap.TokenEntry<String, Object> entry = tokenMap.get(key);
                    if (now - entry.time >= CLEAR_TIMEOUT) {
                        synchronized (tokenMap) {
                            logger.info("[删除过期key:" + key+"]");
                            tokenMap.remove(key);
                        }
                    }
                }
                try {
                    Thread.sleep(CHECK_TIMEOUT);
                } catch (Exception e) {
                    logger.error("[tokenMap Error]", e);
                }
            }
        }
    }

    public Object get(String key) {
        TokenMap.TokenEntry<String, Object> entry = tokenMap.get(key);
        return entry == null ? null : entry.value;
    }

    public Object put(String key, Object value) {
        TokenMap.TokenEntry<String, Object> entry = new TokenMap.TokenEntry<String, Object>(key, value);
        synchronized (tokenMap) {
            tokenMap.put(key, entry);
        }
        return value;
    }

    public boolean containsKey(String key) {
        return tokenMap.containsKey(key);
    }

    public Object remove(String key) {
        return tokenMap.remove(key);
    }


}
